package javapop.framework;

public class DefaultParseResult<T> implements ParseResult<T> {
	private ParsePosition start;
	private ParsePosition end;
	private T result;
	private Class<T> resultClass;
	
	public DefaultParseResult(Class<T> resultClass, T result) {
		this.start = null;
		this.end = null;
		this.result = result;
		this.resultClass = resultClass;
	}

	public boolean checkType() {
		if(result==null)
			return false;
		return result.getClass()==resultClass;
	}
	
	public void checkTypeWithExplanations() throws TypeError {
		if(result==null)
			throw new TypeError("<null> parse result");
		if(result.getClass()!=resultClass) {
			throw new TypeError("Expecting result of type '" + resultClass.getName() + "' got '"+result.getClass()+"'");
		}
	}

	public ParsePosition getStart() {
		return start;
	}
	
	public void setStart(ParsePosition start) {
		this.start = start;
	}

	public ParsePosition getEnd() {
		return end;
	}

	public void setEnd(ParsePosition end) {
		this.end = end;
	}

	public T getResult() {
		return result;
	}

	public Class<T> getResultClass() {
		return resultClass;
	}
	
	public boolean isError() {
		return false;
	}
	
	@Override
	public final ParseError asError() {
		if(!isError()) {
			throw new IllegalStateException("Not a parse error");
		} else {
			return (ParseError) this;
		}
	}
	
	public boolean isNull() {
		return false;
	}
	
	@Override
	public String getInputString(ParseInput input) {
		return input.extract(start.getPos(),end.getPos());
	}
	
	@Override
	public String getErrorMessage() {
		throw new Error("Not a parse error");
	}
	
	@Override
	public String getDetailedErrorMessage() {
		throw new Error("Not a parse error");
	}

	@Override
	public String toString() {
		StringBuffer buf = new StringBuffer();
		buf.append("ParseResult[");
		buf.append("start="); buf.append(start);
		buf.append(",end="); buf.append(end);
		if(resultClass!=null) {
			buf.append(",type="); buf.append(resultClass.getName());
		}
		buf.append("{ \n");
		buf.append("  ");
		buf.append(result);
		buf.append("\n}");
		return buf.toString();
	}
	
}
